#include "TaskQueue.h"

using namespace std;
using namespace threadpool;

void TaskQueue::push(shared_ptr<Task> task) {
    lock_guard<mutex> lock(mutex_);
    queue_.push(std::move(task));
    cond_.notify_one();
}

shared_ptr<Task> TaskQueue::top() {
    lock_guard<mutex> lock(mutex_);
    return queue_.top();
}

std::shared_ptr<Task> TaskQueue::pop() {
    std::unique_lock<std::mutex> lock(mutex_);
    cond_.wait(lock, [this]() { return !queue_.empty() || stop_.load(); });
    if (stop_.load() || queue_.empty()) {
        return nullptr;
    }
    auto task = queue_.top();
    queue_.pop();
    return task;
}

bool TaskQueue::empty() {
    lock_guard<mutex> lock(mutex_);
    return queue_.empty();
}

size_t TaskQueue::size() {
    lock_guard<mutex> lock(mutex_);
    return queue_.size();
}

void TaskQueue::stop() {
    std::lock_guard<std::mutex> lock(mutex_);
    stop_.store(true);
    cond_.notify_all();
}
